/*
 * SelectionStrategyTournament.cpp
 *
 *  Created on: Oct 22, 2013
 *      Author: filipe
 */

#include <cstdlib>
#include <cstring>
#include "SelectionStrategyTournament.h"

namespace EvolutionaryOptimization
{
	SelectionStrategyTournament::SelectionStrategyTournament(int population_size) : SelectionStrategy(population_size)
	{
		_PopulationSize = population_size;
		_PopulationFitness = (double *) calloc (_PopulationSize, sizeof(double));
	}


	SelectionStrategyTournament::~SelectionStrategyTournament()
	{
		free(_PopulationFitness);
	}


	void
	SelectionStrategyTournament::InitializeSelector(double *fitness)
	{
		memcpy(_PopulationFitness, fitness, _PopulationSize * sizeof(double));
	}


	Parents
	SelectionStrategyTournament::GetNextParents()
	{
		// TODO: this implementation is more readable but less efficient. To make it faster
		// create the full list of parents in the InitializeSelector method and just return
		// one of them each time this method is called.

		Parents p;
		int possible_parent_a;
		int possible_parent_b;

		// select the first parent
		possible_parent_a = rand() % _PopulationSize;
		possible_parent_b = rand() % _PopulationSize;

		if (_PopulationFitness[possible_parent_a] > _PopulationFitness[possible_parent_b])
			p.SetFirstParent(possible_parent_a);
		else
			p.SetFirstParent(possible_parent_b);

		// select the second parent
		possible_parent_a = rand() % _PopulationSize;
		possible_parent_b = rand() % _PopulationSize;

		if (_PopulationFitness[possible_parent_a] > _PopulationFitness[possible_parent_b])
			p.SetSecondParent(possible_parent_a);
		else
			p.SetSecondParent(possible_parent_b);

		return p;
	}
}
